package com.neulogistics.contrib.usercenter.api.application.integrationevent;

import com.blackto.lib.eventbus.abstraction.IEventBus;
import com.blackto.lib.eventbus.event.IntegrationEvent;
import com.neulogistics.infrastructure.integrationeventlog.model.IntegrationEventLogEntry;
import com.neulogistics.infrastructure.integrationeventlog.service.IIntegrationEventLogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Slf4j
@Service
public class UserCenterIntegrationEventService implements IUserCenterIntegrationEventService {
    @Resource
    private IEventBus eventBus;

    @Resource
    private IIntegrationEventLogService integrationEventLogService;

    @Value("${spring.application.name}")
    private String appName;

    @Override
    public void addAndSaveEvent(IntegrationEvent integrationEvent, long transactionId) {
        log.info("----- Enqueuing integration event {} to repository ({})",
                integrationEvent.getEventId(), integrationEvent);
        integrationEventLogService.saveEvent(integrationEvent, transactionId);
    }

    @Override
    public void publishEvents(long transactionId) {
        List<IntegrationEventLogEntry> pendingLogEvents =
                integrationEventLogService.retrieveEventLogsPendingToPublish(transactionId);
        // 对所有未发布事件进行发布
        for(IntegrationEventLogEntry entry : pendingLogEvents){
            log.info("----- Publishing integration event: {} from {} - ({})",
                    entry.getEventId().toString(), appName,
                    entry.getIntegrationEvent());
            try {
                integrationEventLogService.markEventAsInProgress(entry.getEventId());
                eventBus.publish(entry.getIntegrationEvent());
                integrationEventLogService.markEventAsPublished(entry.getEventId());
            } catch (Exception e){
                log.error("ERROR publishing integration event: {} from {}, {}",
                        entry.getEventId().toString(), appName, e.getMessage());
                integrationEventLogService.markEventAsFailed(entry.getEventId());
            }

        }
    }
}
